(function (layui, window, factory) {
    if (typeof exports === 'object') { // 支持 CommonJS
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) { // 支持 AMD
        define(factory);
    } else if (window.layui && layui.define) { //layui加载
        layui.define(['jquery', 'laypage', 'laytpl'], function (exports) {
            exports('mobileTable', factory());
        });
    } else {
        window.formSelects = factory();
    }
})(typeof layui == 'undefined' ? null : layui, window, function () {
    let v = '0.1',
        $ = window.$ || (window.layui && window.layui.jquery),
        laypage = window.layui.laypage,
        laytpl = window.layui.laytpl,
        CLASSNAME = 'mobile-table',
        TOGGLE_COL_WIDTH = '2rem';

    let Common = function () {
    };
    /**
     * 表格渲染
     *
     * @param $elem
     * @param options
     */
    Common.prototype.render = function ($elem, options) {
        var cols = options.cols;
        var {leftCols, rightCols, mainMajorCols, mainMinorCols, detailCols} = this.getCols(cols);
        $elem.data("leftCols", leftCols);
        $elem.data("rightCols", rightCols);
        $elem.data("mainMajorCols", mainMajorCols);
        $elem.data("mainMinorCols", mainMinorCols);
        $elem.data("detailCols", detailCols);
        $elem.data("options", options);

        $elem.html("");
        $elem.append("<div class='" + CLASSNAME + "-header'></div>");
        $elem.append("<div class='" + CLASSNAME + "-body'></div>");
        $elem.append("<div class='" + CLASSNAME + "-pager' style='display: none;'></div>");

        this.renderHeader($elem);
        if (options.rows) {
            this.renderBody($elem, options.rows);
        }
        if (options.url) {
            this.renderBodyWithUrl($elem, options.url);
        }
    };
    /**
     * 获取表格列配置
     *
     * @param cols
     * @returns {{leftCols, rightCols, mainMajorCols, mainMinorCols, detailCols}}
     */
    Common.prototype.getCols = function (cols) {
        var leftCols = {};
        var rightCols = {};
        var mainMajorCols = {};
        var mainMinorCols = {};
        var detailCols = {};

        for (var field in cols) {
            var col = cols[field];
            col.field = field;
            if (col.ignore) {
                continue;
            }
            if (!col.title) {
                col.title = field;
            }
            if (!col.align) {
                col.align = 'center';
            }
            var position = col.position || 'detail';
            if (!position instanceof Array) {
                position = [position];
            }
            if (position.indexOf("left") !== -1 && !col.hide) {
                leftCols[field] = col;
            }
            if (position.indexOf("right") !== -1 && !col.hide) {
                rightCols[field] = col;
            }
            if (position.indexOf("major") !== -1 && !col.hide) {
                mainMajorCols[field] = col;
            }
            if (position.indexOf("minor") !== -1 && !col.hide) {
                mainMinorCols[field] = col;
            }
            if (position.indexOf("!detail") === -1) {
                //如果没有明确指定不在detail区域显示，则默认需要显示
                detailCols[field] = col;
            }
        }
        //如果major列没有设置，则minor自动显示在detail区域
        if (JSON.stringify(mainMajorCols) == "{}") {
            for (var field in mainMinorCols) {
                detailCols[field] = mainMinorCols[field];
            }
            mainMinorCols = {};
        }

        /////////////////////////////////////////////////////////////
        // 重设列的宽度
        var unWidthColCount = 0;
        var widthColSum = "0px";
        for (var field in leftCols) {
            if (!leftCols[field].width) {
                unWidthColCount++;
            } else {
                if (isNaN(leftCols[field].width)) {
                    leftCols[field].width += "px";
                }
                widthColSum += " + " + leftCols[field].width;
            }
        }
        for (var field in mainMajorCols) {
            if (!mainMajorCols[field].width) {
                unWidthColCount++;
            } else {
                if (isNaN(mainMajorCols[field].width)) {
                    mainMajorCols[field].width += "px";
                }
                widthColSum += " + " + mainMajorCols[field].width;
            }
        }
        for (var field in rightCols) {
            if (!rightCols[field].width) {
                unWidthColCount++;
            } else {
                if (isNaN(rightCols[field].width)) {
                    rightCols[field].width += "px";
                }
                widthColSum += " + " + rightCols[field].width;
            }
        }

        if (unWidthColCount > 0) {
            var unWidthAvg = "calc((100% - " + TOGGLE_COL_WIDTH + " - ( " + widthColSum + " )) / " + unWidthColCount + ")";
            for (var field in leftCols) {
                leftCols[field].width = unWidthAvg;
            }
            for (var field in mainMajorCols) {
                mainMajorCols[field].width = unWidthAvg;
            }
            for (var field in rightCols) {
                rightCols[field].width = unWidthAvg;
            }
        }
        return {leftCols, rightCols, mainMajorCols, mainMinorCols, detailCols};
    };
    /**
     * 生成表格头部元素
     *
     * @param $elem
     * @returns {*|HTMLElement}
     */
    Common.prototype.renderHeader = function ($elem) {
        var leftCols = $elem.data("leftCols");
        var mainMajorCols = $elem.data("mainMajorCols");
        var rightCols = $elem.data("rightCols");

        var html = "<div class='line'>";
        for (var field in leftCols) {
            html += this.generateHeaderItemHtml(leftCols[field], "left");
        }
        for (var field in mainMajorCols) {
            html += this.generateHeaderItemHtml(mainMajorCols[field], "major");
        }
        for (var field in rightCols) {
            html += this.generateHeaderItemHtml(rightCols[field], "right");
        }
        html += "<div class='header-item toggle-header-item' style='width: " + TOGGLE_COL_WIDTH + ";'>";
        html += "</div>";

        html += "</div>";

        var $header = $elem.find("." + CLASSNAME + "-header");
        $header.html(html);
        //如果没有列显示，则隐藏头部
        if (JSON.stringify(leftCols) == "{}" && JSON.stringify(mainMajorCols) == "{}" && JSON.stringify(rightCols) == "{}") {
            $header.hide();
        }
    };
    /**
     * 生成表格头部单元格html
     *
     * @param col
     * @param position
     * @returns {string}
     */
    Common.prototype.generateHeaderItemHtml = function (col, position) {
        var style = "width: " + col.width + ";";
        var html = "";
        html += "<div class='header-item " + position + "-header-item' style='" + style + "'>";
        html += "<span class='title'>" + col.title + "</span>";
        html += "</div>";
        return html;
    };
    /**
     * 生成数据表主体
     *
     * @param $elem
     * @param rows
     * @returns {*|HTMLElement}
     */
    Common.prototype.renderBody = function ($elem, rows) {
        var leftCols = $elem.data("leftCols");
        var mainMajorCols = $elem.data("mainMajorCols");
        var mainMinorCols = $elem.data("mainMinorCols");
        var rightCols = $elem.data("rightCols");
        var detailCols = $elem.data("detailCols");
        var options = $elem.data("options");

        if (!(rows instanceof Array)) {
            rows = [];
        }
        var rowHeight = options.rowHeight || 2;
        var mainMajorRowHeight = options.majorRowHeight || (options.rowHeight - 1);
        var mainMinorRowHeight = rowHeight - mainMajorRowHeight;

        //是否隐藏brief行
        var hideBrief = false;
        if (JSON.stringify(leftCols) == "{}" && JSON.stringify(mainMajorCols) == "{}" && JSON.stringify(rightCols) == "{}") {
            hideBrief = true;
        }
        var briefStyle = hideBrief ? "display: none;" : "";
        var detailStyle = hideBrief ? "" : "display: none;";

        var html = "";
        for (var i = 0; i < rows.length; i++) {
            var row = rows[i];
            html += "<div class='row'>";
            html += "<div class='line brief' style='" + briefStyle + "'>";

            var leftColWidthSum = "0px";
            for (var field in leftCols) {
                var col = leftCols[field];
                html += this.generateDataItemHtml(col, "left", row[field] || "", row, rowHeight);
                leftColWidthSum += " + " + col.width;
            }

            var majorColWidthSum = "0px";
            for (var field in mainMajorCols) {
                var col = mainMajorCols[field];
                html += this.generateDataItemHtml(col, "major", row[field] || "", row, mainMajorRowHeight);
                majorColWidthSum += " + " + col.width;
            }
            for (var field in rightCols) {
                html += this.generateDataItemHtml(rightCols[field], "right", row[field] || "", row, rowHeight);
            }

            var toggleStyle = "width: " + TOGGLE_COL_WIDTH + ";" +
                "height: " + rowHeight + "rem;" +
                "line-height: " + rowHeight + "rem;";
            html += "<div class='body-item toggle-body-item' style='" + toggleStyle + "'>";
            html += "<i class='layui-icon layui-icon-up'></i>";
            html += "<i class='layui-icon layui-icon-down'></i>";
            html += "</div>";

            var minorStyle = "margin-left: calc( " + leftColWidthSum + " );" +
                "width: calc( " + majorColWidthSum + " );" +
                "height: " + mainMinorRowHeight + "rem;" +
                "line-height: " + mainMinorRowHeight + "rem;" +
                "margin-top: " + mainMajorRowHeight + "rem;";
            html += "<div class='minor-line' style='" + minorStyle + "'>";
            for (var field in mainMinorCols) {
                var col = mainMinorCols[field];
                html += "<span class='item'>";
                html += "<span class='label'>" + col.title + "：</span>";
                html += "<span class='val'>" + this.templetVal(col, row[field] || "", row) + "</span>";
                html += "</span>";
            }
            html += "</div>";

            html += "</div>";

            html += "<div class='line detail' style='" + detailStyle + "'>";
            html += "<div class='layui-row'>";
            for (var field in detailCols) {
                var col = detailCols[field];
                var detailWidth = col.detailWidth || 6;
                html += "<div class='layui-col-xs" + detailWidth + " detail-item'>";
                html += "<span class='label'>" + col.title + "：</span>";
                html += "<span class='val'>" + this.templetVal(col, row[field] || "", row) + "</span>";
                html += "</div>";
            }
            html += "</div>";
            html += "</div>";

            html += "</div>";
        }

        $elem.find("." + CLASSNAME + "-body").html(html);

        options.rows = rows;
        $elem.data("options", options);
    };
    /**
     * 生成数据项html
     *
     * @param col
     * @param position
     * @param val
     * @param row
     * @param rowHeight
     * @returns {string}
     */
    Common.prototype.generateDataItemHtml = function (col, position, val, row, rowHeight) {
        val = this.templetVal(col, val, row);

        var style = "width: " + col.width + ";" +
            "text-align: " + col.align + ";" +
            "height: " + rowHeight + "rem;" +
            "line-height: " + rowHeight + "rem;";
        var html = "";
        html += "<div class='body-item " + position + "-body-item' style='" + style + "'>";
        html += "<span class='val'>" + val + "</span>";
        html += "</div>";
        return html;
    };
    /**
     * 格式化值
     *
     * @param col
     * @param val
     * @param row
     * @returns {*}
     */
    Common.prototype.templetVal = function (col, val, row) {
        if (col.templet) {
            val = typeof col.templet === 'function' ? col.templet(row) : laytpl($(col.templet).html() || String(val)).render(row);
        }
        return val;
    };
    /**
     * 利用远程数据渲染表格
     *
     * @param $elem
     * @param url
     */
    Common.prototype.renderBodyWithUrl = function ($elem, url) {
        var options = $elem.data("options");
        var that = this;
        var params = {};
        params.page = (options.page && options.page.curr) || 1;
        params.limit = options.limit;

        //参数
        var data = $.extend(params, options.where);
        if (options.contentType && options.contentType.indexOf("application/json") == 0) { //提交 json 格式
            data = JSON.stringify(data);
        }

        $.ajax({
            type: options.method || 'get'
            , url: url
            , contentType: options.contentType
            , data: data
            , dataType: 'json'
            , headers: options.headers || {}
            , success: function (res) {
                //如果有数据解析的回调，则获得其返回的数据
                if (typeof options.parseData === 'function') {
                    res = options.parseData(res) || res;
                }
                if (res.success) {
                    that.renderBody($elem, res.data);
                    that.renderPager($elem, {
                        count: res.count,
                        curr: res.page,
                        limit: res.limit
                    });
                } else {
                    that.alert("数据接口请求异常：" + res.msg);
                }
            }
            , error: function (e, m) {
                that.alert("数据接口请求异常：" + m);
            }
        });
    };
    /**
     * 生成分页组件
     *
     * @param $elem
     * @param page
     */
    Common.prototype.renderPager = function ($elem, page) {
        var $pager = $elem.find("." + CLASSNAME + "-pager");
        if (!page || (page.count && page.limit && page.count <= page.limit)) {
            $pager.hide();
            return;
        }
        $pager.show();
        $pager.each(function () {
            var pageConfig = $.extend({
                elem: this,
                groups: 1
            }, page);
            laypage.render(pageConfig);
        });
    };
    /**
     * 向页面注入css
     */
    Common.prototype.injectCss = function () {
        var link = document.createElement('link');
        document.body.appendChild(link);
        link.setAttribute('rel', 'stylesheet');
        link.setAttribute('href', '/static/layui/mods/mobileTable/mobileTable.css');
        link.setAttribute('type', 'text/css');
    };
    /**
     * 绑定事件
     *
     * @param $elem
     */
    Common.prototype.bindEvent = function () {
        $(".mobile-table").delegate(".line.brief", "click", function () {
            $(".toggle-body-item", this).toggleClass("toggled-body-item");
            $(this).next(".detail").toggle();
        });
    };
    let common = new Common();

    let MobileTable = function () {
        this.v = v;
        common.injectCss();
        common.bindEvent();
    };

    /**
     * 渲染
     *
     * @param id
     * @param options
     * @returns {MobileTable}
     */
    MobileTable.prototype.render = function (id, options) {
        options = $.extend({}, options);
        common.render($("#" + id), options);
        return this;
    };

    return new MobileTable();
});